package com.itlong.cloud.controller.settings;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.zxing.BarcodeFormat;
import com.itlong.cloud.POJO.DTO.common.PadFaceSyncDataDTO;
import com.itlong.cloud.POJO.DTO.property.*;
import com.itlong.cloud.POJO.PO.ProductTypePO;
import com.itlong.cloud.POJO.PO.ProjectPO;
import com.itlong.cloud.POJO.PO.SysCodePO;
import com.itlong.cloud.POJO.PO.TimeTaskAuthDeviceAddressInfoPO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.operate.OperateProjectRelatedProductVO;
import com.itlong.cloud.POJO.VO.property.*;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.abstracts.BaseController;
import com.itlong.cloud.annotation.AuthAccessRequired;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.annotation.UnAuthAccessRequired;
import com.itlong.cloud.annotation.UnParamEncrypt;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.enumerate.*;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.OperateErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.PropertyErrorCodeEnum;
import com.itlong.cloud.equip.property.*;
import com.itlong.cloud.noncore.commons.IDataDictionaryServiceClient;
import com.itlong.cloud.paymenthub.IWeChatPayServiceClient;
import com.itlong.cloud.project.operate.IOperateProductTypeServiceClient;
import com.itlong.cloud.project.operate.IOperateProjectServiceClient;
import com.itlong.cloud.project.property.IPropertyBuildInfoServiceClient;
import com.itlong.cloud.project.property.IPropertyRoomInfoServiceClient;
import com.itlong.cloud.project.property.IPropertyUnitInfoServiceClient;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.property.IPropertyHouseHoldInfoServiceClient;
import com.itlong.cloud.utils.encrypt.DesEncryptUtil;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.file.UploadFileUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.node.SetListUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.picture.QrcodeUtils;
import com.itlong.cloud.utils.words.NumberHandlerUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <desc>
 * 物业系统设备聚合Controller。
 * </desc>
 *
 * @createDate 2017/09/20
 */
@RestController
@RequestMapping("/settings/equip")
@RefreshScope
public class PropertyEquipController extends BaseController {

    private static Logger LOG = LoggerFactory.getLogger(PropertyEquipController.class);
    //物业设备服务层暴露接口
    @Autowired
    IPropertyEquipServiceClient iPropertyEquipServiceClient;

    @Autowired
    IPropertyBuildInfoServiceClient iPropertyBuildInfoServiceClient;

    @Autowired
    IPropertyUnitInfoServiceClient iPropertyUnitInfoServiceClient;

    @Autowired
    IPropertyRoomInfoServiceClient iPropertyRoomInfoServiceClient;

    @Autowired
    IDataDictionaryServiceClient iDataDictionaryServiceClient;

    @Autowired
    IPropertyHouseHoldInfoServiceClient iPropertyHouseHoldInfoServiceClient;

    //物业项目服务层暴露接口
    @Autowired
    IOperateProjectServiceClient iOperateProjectServiceClient;

    //产品型号信息服务协议接口
    @Autowired
    IOperateProductTypeServiceClient iOperateProductTypeServiceClient;

    //设备权限接口服务
    @Autowired
    IPropertyDeviceAuthServiceClient iPropertyDeviceAuthServiceClient;

    @Autowired
    IPropertyEquipRecordServiceClient iPropertyEquipRecordServiceClient;

    @Autowired
    IPadFaceSyncDataServiceClient iPadFaceSyncDataServiceClient;

    @Autowired
    IPropertyPadServiceClient iPropertyPadServiceClient;

    @Value("${" + PlatformConstants.FILE_FTP_HOST + "}")
    public String FILE_FTP_HOST;

    @Value("${" + PlatformConstants.FILE_FTP_PORT + "}")
    public String FILE_FTP_PORT;

    @Value("${" + PlatformConstants.FILE_FTP_USERNAME + "}")
    public String FILE_FTP_USERNAME;

    @Value("${" + PlatformConstants.FILE_FTP_PASSWORD + "}")
    public String FILE_FTP_PASSWORD;

    @Value("${" + PlatformConstants.FILE_ACCESS_URL + "}")
    public String FILE_ACCESS_URL;

    /**
     * <desc>
     *      获取电梯楼层对应表
     * <desc/>
     *
     * @return 标准格式化响应结果
     * @author Jiaqi.X
     * @createDate 2020/03/27
     */
    @ResponseBody
    @RequestMapping(path = "/getFloorByDeviceUnique")
    public Object getFloorByDeviceUnique(String deviceUnique,HttpServletRequest request) {
        try {
            deviceUnique  = request.getAttribute("deviceUnique") == null ? null : request.getAttribute("deviceUnique").toString();
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),iPropertyEquipServiceClient.getFloorByDeviceUnique(deviceUnique));
        } catch (Exception e) {
            throw new DataAccessException("【物业系统_setStandbyInterface】设置云对讲设备的待机界面失败", e);
        }
    }

    /**
     * <desc>
     *      获取项目云电梯列表
     * <desc/>
     *
     * @return 标准格式化响应结果
     * @author Jiaqi.X
     * @createDate 2020/03/27
     */
    @ResponseBody
    @RequestMapping(path = "/getElevatorLiftByProjectId")
    public Object getElevatorLiftByProjectId(String projectId,String unitId,String type,String floorNum,HttpServletRequest request) {
        try {
            projectId  = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            unitId = request.getAttribute("unitId") == null ? null : request.getAttribute("unitId").toString();
            type = request.getAttribute("type") == null ? null : request.getAttribute("type").toString();
            floorNum = request.getAttribute("floorNum") == null ? null : request.getAttribute("floorNum").toString();
            if(StringUtils.isNotBlank(type) && type.equals("1")){
                if(StringUtils.isBlank(unitId) || StringUtils.isBlank(floorNum)){
                    return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),new ArrayList<PropertyGetElevatorNameAndDeviceUniqueVO>());
                }
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),iPropertyEquipServiceClient.getElevatorByProjectId(projectId,unitId,floorNum));
        } catch (Exception e) {
            throw new DataAccessException("【物业系统_setStandbyInterface】设置云对讲设备的待机界面失败", e);
        }
    }

    /**
     * <desc>
     * 设备管理中添加设备：电梯、门禁或云对讲
     * <desc/>
     *
     * @param propertyEquipSaveDTO 物业设备数据传输对象
     * @return MessageVO 标准格式化响应结果
     * @author Biao.R
     * @createDate 2017/11/6
     */
    @PostMapping(path = "/save")
    @ResponseBody
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.EQUIP_SAVEEQUIP_INFO_LOG_DESC)
    public Object savePropertyEquip(PropertyEquipSaveDTO propertyEquipSaveDTO) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyEquipSaveDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyEquipSaveDTO.class, request);
            Integer deviceType = propertyEquipSaveDTO.getDeviceType();
            String projectId = propertyEquipSaveDTO.getProjectId();
            //如果本项目已添加有效的批次号后，则需校验设备总数与项目下批次号之和的数量
            List<String> str= iPropertyEquipServiceClient.getBatchNumber(projectId,"0");
            if(str != null && !str.isEmpty()&&(propertyEquipSaveDTO.getElevatorType()==null || propertyEquipSaveDTO.getElevatorType() != 13)){
                Integer deviceCountByProject = iPropertyEquipServiceClient.getDeviceCountByType(deviceType,projectId,"");
                Integer limitCountByProject = iPropertyEquipServiceClient.getDeviceCountByBatchNumber(projectId,deviceType+"","");
                deviceCountByProject = deviceCountByProject==null?0:deviceCountByProject;
                if(limitCountByProject==null || limitCountByProject<=deviceCountByProject){
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_COUNT_PROJECT_IS_ZERO.getErrorCode());
                }
            }

            //如果批次号不为空时则需校验批次号相对应的设备数量
            if(StringUtils.isNotEmpty(propertyEquipSaveDTO.getBatchNumber())&&(propertyEquipSaveDTO.getElevatorType()==null || propertyEquipSaveDTO.getElevatorType() != 13)){
                Integer deviceCount = iPropertyEquipServiceClient.getDeviceCountByType(deviceType,projectId,propertyEquipSaveDTO.getBatchNumber());
                Integer limitCount = iPropertyEquipServiceClient.getDeviceCountByBatchNumber(projectId,deviceType+"",propertyEquipSaveDTO.getBatchNumber());
                if(deviceCount == null){
                    deviceCount = 0;
                }
                if(limitCount<=deviceCount){
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_COUNT_PROJECT_IS_LESS.getErrorCode());
                }
            }

            //设备类型和机号范围合法性校验
            if(propertyEquipSaveDTO.getElevatorType()==null || propertyEquipSaveDTO.getElevatorType() != 13) {
                MessageVO messageVO = this.saveAndUpdateCheck(propertyEquipSaveDTO);
                if (messageVO != null) {
                    return messageVO;
                }
            }
            String[] buildIdArr = null;
            String[] unitIdArr = null;
            String buildIds = propertyEquipSaveDTO.getBuildIds();
            String unitIds = propertyEquipSaveDTO.getUnitIds();
            if (StringUtils.isNotEmpty(buildIds)) {
                buildIdArr = buildIds.split(",");
            }
            if (StringUtils.isNotEmpty(unitIds)) {
                unitIdArr = unitIds.split(",");
            }

            PropertyCloudIntercomSaveDTO equipAddDTO = new PropertyCloudIntercomSaveDTO();
            BeanUtils.copyProperties(propertyEquipSaveDTO, equipAddDTO);
            String deviceId = String.format("%04d", propertyEquipSaveDTO.getDeviceId());
            equipAddDTO.setDeviceId(deviceId);
            String deviceUnique = String.format("%s%d%s", projectId, deviceType, deviceId);

            String newDeviceUnique = String.format("%s%d%s", projectId, deviceType, deviceId);
            if(propertyEquipSaveDTO.getElevatorType()!=null && propertyEquipSaveDTO.getElevatorType() == 13){
                newDeviceUnique = String.format("%s%d%s", projectId, 4, deviceId);
            }
            //该设备唯一码的设备存在性校验
            PropertyEquipGetVO getVO = iPropertyEquipServiceClient.getByDeviceUnique(newDeviceUnique);
            if (getVO != null && getVO.getStatus()!=0) {
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_DEVICEUNIQUE_IS_EXIST.getErrorCode());
            }
            if (getVO != null && getVO.getStatus()==0) {
                //删除status=0的旧数据
                iPropertyEquipServiceClient.deleteByDeviceUnique(getVO.getDeviceUnique());
            }

            equipAddDTO.setDeviceUnique(deviceUnique);
            if (PropertyEquipTypeEnum.CLOUD_INTERCOM.getType() == deviceType) {

                //该项目是否启用云对讲设备
                Integer isSmartCommunity = iOperateProjectServiceClient.getIsSmartCommunity(projectId);
                if (isSmartCommunity != ProjectSmartCommunityStatusEnum.PROJECT_SMART_COMMUNITY_YES.getType()) {
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_PROJECT_IS_NOT_SMARTCOMMUNITY.getErrorCode());
                }
                //云对讲设备其他参数预处理：包含生成Sn规则
                equipAddDTO = this.cloudIntercomeHandle(equipAddDTO);
            }
            if (PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType() == propertyEquipSaveDTO.getElevatorType()) {

                ProductTypePO productTypePO = iPropertyEquipServiceClient.getTypeId(PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType());
                if(productTypePO==null){
                    return new MessageVO(PropertyErrorCodeEnum.CLOUD_ELEVTAOR_IS_NOT_TYPE_ID.getErrorCode());
                }
                equipAddDTO.setProductTypeId(productTypePO.getTypePid());

                //云电梯设备其他参数预处理：包含生成Sn规则
                equipAddDTO = this.cloudIntercomeHandle(equipAddDTO);
            }
            if (PropertyEquipTypeEnum.CLOUD_ENTRANCE_DEVICE.getType() == propertyEquipSaveDTO.getEntranceCategory()
                    || PropertyEquipTypeEnum.CLOUD_WIPPEN_DEVICE.getType() == propertyEquipSaveDTO.getEntranceCategory()
                    || PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType() == propertyEquipSaveDTO.getEntranceCategory()
                    || PropertyEquipTypeEnum.CLOUD_UNIBODY_ENTRANCE_DEVICE.getType() == propertyEquipSaveDTO.getEntranceCategory()) {
                equipAddDTO.setSupportFunction("4,6");
                ProductTypePO productTypePO = iPropertyEquipServiceClient.getTypeId(PropertyEquipTypeEnum.CLOUD_ENTRANCE_DEVICE.getType());
                if(productTypePO==null){
                    return new MessageVO(PropertyErrorCodeEnum.ENTRANCE_IS_NOT_TYPE_ID.getErrorCode());
                }
                equipAddDTO.setProductTypeId(productTypePO.getTypePid());

                //云门禁设备其他参数预处理：包含生成Sn规则
                equipAddDTO = this.cloudIntercomeHandle(equipAddDTO);
            }


            //设备机号重复性校验
            if(propertyEquipSaveDTO.getElevatorType()==null || propertyEquipSaveDTO.getElevatorType() != 13) {
                PropertyEquipGetDTO deviceIdCheck = new PropertyEquipGetDTO(deviceType, deviceId, projectId);
                List<PropertyEquipGetVO> deviceIdCheckVOS = iPropertyEquipServiceClient.checkEquip(deviceIdCheck);
                if (deviceIdCheckVOS != null && !deviceIdCheckVOS.isEmpty()) {
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_DEVICEID_IS_EXIST.getErrorCode());
                }
                //设备名称重复性校验
                PropertyEquipGetDTO deviceNameCheck = new PropertyEquipGetDTO(projectId);
                deviceNameCheck.setDeviceType(deviceType);
                deviceNameCheck.setDeviceName(propertyEquipSaveDTO.getDeviceName());
                List<PropertyEquipGetVO> deviceNameCheckVOS = iPropertyEquipServiceClient.checkEquip(deviceNameCheck);
                if (deviceNameCheckVOS != null && !deviceNameCheckVOS.isEmpty()) {
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_DEVICENAME_IS_EXIST.getErrorCode());
                }
            }

            Set<String> unitIdSet = new HashSet<>();

            //处理改变的设备地址给权限队列
            if(propertyEquipSaveDTO.getEntranceType()!=EntranceTypeEnum.COMMON_ENTRANCE.getType() ){
                if (unitIdArr != null) {
                    //1栋多单元
                    unitIdSet.addAll(Arrays.asList(unitIdArr));
                } else {
                    //多栋
                    Set<String> buildIdSet = new HashSet<>();
                    buildIdSet.addAll(Arrays.asList(buildIdArr));
                    List<String> unitIdList = iPropertyUnitInfoServiceClient.getUnitIdInBuildIds(String.join(",", buildIdSet));
                    unitIdSet.addAll(unitIdList);

                }
                Date date = new Date();
                //地址发生变化，将变化的地址存储的到定时任务表中
                TimeTaskAuthDeviceAddressInfoPO deviceAddrPO = new TimeTaskAuthDeviceAddressInfoPO(projectId, propertyEquipSaveDTO.getLoginUserId(), String.join(",", unitIdSet), DataStatusEnum.NORMAL.getType(), date, date);
                equipAddDTO.setTimeTaskAuthDeviceAddressInfoPO(deviceAddrPO);
            }

            if(equipAddDTO.getElevatorType()!=null && equipAddDTO.getElevatorType() == 13){
                deviceUnique = String.format("%s%s%s", projectId, "4", deviceId);
                equipAddDTO.setDeviceUnique(deviceUnique);
            }
            iPropertyEquipServiceClient.addPropertyEquip(equipAddDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());

        } catch (Exception e) {
            throw new DataAccessException("【物业_系统_设备管理】添加设备失败", e);
        }
    }


    /**
     * <desc>
     * 设备管理中更新设备：电梯、门禁或云对讲
     * <desc/>
     *
     * @param propertyEquipSaveDTO 物业设备数据传输对象
     * @return MessageVO 标准格式化响应结果
     * @author Biao.R
     * @createDate
     */
    @PostMapping(path = "/update")
    @ResponseBody
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.EQUIP_UPDATEEQUIP_INFO_LOG_DESC)
    public Object updatePropertyEquip(PropertyEquipSaveDTO propertyEquipSaveDTO) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyEquipSaveDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyEquipSaveDTO.class, request);
            String projectId = propertyEquipSaveDTO.getProjectId();
            Integer deviceType = propertyEquipSaveDTO.getDeviceType();
            String deviceUnique = propertyEquipSaveDTO.getDeviceUnique();
            PropertyEquipGetVO oldEquip = iPropertyEquipServiceClient.getByDeviceUnique(deviceUnique);
            //如果批次号不为空时则需校验批次号相对应的设备数量
            if((StringUtils.isNotEmpty(propertyEquipSaveDTO.getBatchNumber()) && (StringUtils.isEmpty(oldEquip.getBatchNumber()) ||
                    (StringUtils.isNotEmpty(oldEquip.getBatchNumber()) && !propertyEquipSaveDTO.getBatchNumber().equals(oldEquip.getBatchNumber()))))
                    &&(propertyEquipSaveDTO.getElevatorType()==null || propertyEquipSaveDTO.getElevatorType() != 13)){
                Integer deviceCount = iPropertyEquipServiceClient.getDeviceCountByType(deviceType,projectId,propertyEquipSaveDTO.getBatchNumber());
                Integer limitCount = iPropertyEquipServiceClient.getDeviceCountByBatchNumber(projectId,deviceType+"",propertyEquipSaveDTO.getBatchNumber());
                if(deviceCount == null){
                    deviceCount = 0;
                }
                if(limitCount<=deviceCount){
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_COUNT_PROJECT_IS_LESS.getErrorCode());
                }
            }
            //设备数据合法性校验
            if(propertyEquipSaveDTO.getElevatorType()==null || propertyEquipSaveDTO.getElevatorType() != 13) {
                MessageVO messageVO = this.saveAndUpdateCheck(propertyEquipSaveDTO);
                if (messageVO != null) {
                    return messageVO;
                }
            }

            PropertyCloudIntercomSaveDTO equipAddDTO = new PropertyCloudIntercomSaveDTO();
            BeanUtils.copyProperties(propertyEquipSaveDTO, equipAddDTO);
            equipAddDTO.setDeviceId(propertyEquipSaveDTO.getDeviceId().toString());
            if (PropertyEquipTypeEnum.CLOUD_INTERCOM.getType() == deviceType || PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType() == propertyEquipSaveDTO.getElevatorType()) {

                //云对讲设备拼接sn,以及其他参数预处理
                equipAddDTO = this.cloudIntercomeHandle(equipAddDTO);
            }
            if (PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType() == propertyEquipSaveDTO.getElevatorType()) {

                ProductTypePO productTypePO = iPropertyEquipServiceClient.getTypeId(PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType());
                if(productTypePO==null){
                    return new MessageVO(PropertyErrorCodeEnum.CLOUD_ELEVTAOR_IS_NOT_TYPE_ID.getErrorCode());
                }
                equipAddDTO.setProductTypeId(productTypePO.getTypePid());

                //云电梯设备其他参数预处理：包含生成Sn规则
                equipAddDTO = this.cloudIntercomeHandle(equipAddDTO);
            }

            if (PropertyEquipTypeEnum.CLOUD_ENTRANCE_DEVICE.getType() == propertyEquipSaveDTO.getEntranceCategory()
                    || PropertyEquipTypeEnum.CLOUD_WIPPEN_DEVICE.getType() == propertyEquipSaveDTO.getEntranceCategory()
                    || PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType() == propertyEquipSaveDTO.getEntranceCategory()
                    || PropertyEquipTypeEnum.CLOUD_UNIBODY_ENTRANCE_DEVICE.getType() == propertyEquipSaveDTO.getEntranceCategory()) {
                equipAddDTO.setSupportFunction("4,6");
                ProductTypePO productTypePO = iPropertyEquipServiceClient.getTypeId(PropertyEquipTypeEnum.CLOUD_ENTRANCE_DEVICE.getType());
                if(productTypePO==null){
                    return new MessageVO(PropertyErrorCodeEnum.ENTRANCE_IS_NOT_TYPE_ID.getErrorCode());
                }
                equipAddDTO.setProductTypeId(productTypePO.getTypePid());

                //门禁设备其他参数预处理：包含生成Sn规则
                equipAddDTO = this.cloudIntercomeHandle(equipAddDTO);
            }

            String newDeviceName = propertyEquipSaveDTO.getDeviceName();
            //设备名称重复性校验
            PropertyEquipGetDTO deviceNameCheck = new PropertyEquipGetDTO(projectId);
            deviceNameCheck.setDeviceType(deviceType);
            deviceNameCheck.setDeviceName(newDeviceName);
            deviceNameCheck.setDeviceUnique(deviceUnique);
            List<PropertyEquipGetVO> deviceNameCheckVOS = iPropertyEquipServiceClient.checkEquip(deviceNameCheck);
            if (deviceNameCheckVOS != null && !deviceNameCheckVOS.isEmpty()) {
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_DEVICENAME_IS_EXIST.getErrorCode());
            }

            if ((PropertyEquipTypeEnum.ELEVATOR.getType() == deviceType)
                    && (oldEquip.getElevatorType()==PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType())
                    && (propertyEquipSaveDTO.getElevatorType()==PropertyEquipTypeEnum.BLUETOOTH_ELEVATOR.getType())) {
                if(iPropertyEquipServiceClient.isBindCloudController(propertyEquipSaveDTO.getDeviceUnique())>0){
                    return new MessageVO(PropertyErrorCodeEnum.CLOUD_ELEVATOR_IS_BING_CLOUD_CONTROLLER.getErrorCode());
                }
            }

            //对比新旧地址
            String[] buildIdArr = null;
            String[] unitIdArr = null;
            String buildIds = propertyEquipSaveDTO.getBuildIds();
            String unitIds = propertyEquipSaveDTO.getUnitIds();
            if (StringUtils.isNotEmpty(buildIds)) {
                buildIdArr = buildIds.split(",");
            }
            if (StringUtils.isNotEmpty(unitIds)) {
                unitIdArr = unitIds.split(",");
            }
            Set<String> newUnitIdSet = new HashSet<>();
            List<String> newBuildIdList = new ArrayList<>();
            if (buildIdArr != null && buildIdArr.length > 0) {
                for (String buildId : buildIdArr) {
                    if (unitIdArr != null && unitIdArr.length > 0) {
                        newUnitIdSet.addAll(Arrays.asList(unitIdArr));
                    } else {
                        newBuildIdList.add(buildId);
                    }
                }
                if (!newBuildIdList.isEmpty()) {
                    List<String> unitIdList = iPropertyUnitInfoServiceClient.getUnitIdInBuildIds(String.join(",", newBuildIdList));
                    newUnitIdSet.addAll(unitIdList);
                }
            }
            //克隆一个未更改的set，直接赋值后newUnitIdSet改变会导致newUnitIdSetCopy值也改变
            Set<String> newUnitIdSetCopy= (Set<String>) ((HashSet<String>) newUnitIdSet).clone();
            Set<String> oldUnitIdSet = this.getEquipOldUnitId(deviceUnique);
            Set<String> diffUnitIdSet = SetListUtil.getDiffSet(oldUnitIdSet, newUnitIdSet);
            //电梯的楼层发生变化会影响该电梯地址下的用户权限，也需要找到电梯地址，并通知权限同步
            if ((PropertyEquipTypeEnum.ELEVATOR.getType() == deviceType) && (oldEquip.getFloorNo()) != (equipAddDTO.getFloorNo())) {
                diffUnitIdSet.addAll(newUnitIdSet);
            }
            if (!diffUnitIdSet.isEmpty() || (!diffUnitIdSet.isEmpty() && (PropertyEquipTypeEnum.ELEVATOR.getType() == deviceType) && oldEquip.getLiftDoorType().equals(propertyEquipSaveDTO.getLiftDoorType()))) {
                //验证更改的设备地址是否在平板所绑定的设备之内，是的话取出平板deviceUnique
                List<String> padDeviceUniqueList = iPropertyPadServiceClient.getPadDeviceUniqueByBindDevice(propertyEquipSaveDTO.getDeviceUnique());
                //当平板不为空的时候更改平板的地址
                if (padDeviceUniqueList.size() != 0){
                    String newUnitIdStr = String.join(",",newUnitIdSetCopy);
                    iPropertyPadServiceClient.updatePadAddress(newUnitIdStr,propertyEquipSaveDTO.getDeviceUnique(),padDeviceUniqueList,propertyEquipSaveDTO.getProjectId());
                }
                Date date = new Date();
                //地址发生变化，将变化的地址存储的到定时任务表中
                TimeTaskAuthDeviceAddressInfoPO deviceAddrPO = new TimeTaskAuthDeviceAddressInfoPO(projectId, propertyEquipSaveDTO.getLoginUserId(), String.join(",", diffUnitIdSet), DataStatusEnum.NORMAL.getType(), date, date);
                deviceAddrPO.setDeviceUniques(deviceUnique);
                equipAddDTO.setTimeTaskAuthDeviceAddressInfoPO(deviceAddrPO);
                //如果云电梯的地址发生变化，需要判断该云电梯有没被云群控器绑定，有则提示地址不允许修改
                if(PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType() == propertyEquipSaveDTO.getElevatorType()){
                    if(iPropertyEquipServiceClient.isBindCloudController(propertyEquipSaveDTO.getDeviceUnique())>0){
                        return new MessageVO(PropertyErrorCodeEnum.EQUIP_ELEVATOR_IS_BING_CLOUD_CONTROLLER.getErrorCode());
                    }
                }
            } else if ((PropertyEquipTypeEnum.ELEVATOR.getType() == deviceType) && !oldEquip.getLiftDoorType().equals(propertyEquipSaveDTO.getLiftDoorType())) {
                Date date = new Date();
                //地址未发生变化，将变化的地址存储的到定时任务表中
                TimeTaskAuthDeviceAddressInfoPO deviceAddrPO = new TimeTaskAuthDeviceAddressInfoPO(projectId, propertyEquipSaveDTO.getLoginUserId(), String.join(",", oldUnitIdSet), DataStatusEnum.NORMAL.getType(), date, date);
                deviceAddrPO.setDeviceUniques(deviceUnique);
                equipAddDTO.setTimeTaskAuthDeviceAddressInfoPO(deviceAddrPO);
            } else {
                //如果设备地址未发生变化，但设备名称发生变化，需要查找所影响的住户，并刷新缓存
                if (!newDeviceName.equals(oldEquip.getDeviceName()) || PropertyEquipTypeEnum.CLOUD_ENTRANCE_DEVICE.getType() == deviceType
                        || PropertyEquipTypeEnum.CLOUD_WIPPEN_DEVICE.getType() == deviceType
                        || PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType() == deviceType
                        || PropertyEquipTypeEnum.CLOUD_UNIBODY_ENTRANCE_DEVICE.getType() == deviceType) {
                    equipAddDTO.setIsOnlyNameChange(true);
                } else {
                    equipAddDTO.setIsOnlyNameChange(false);
                }
            }
            iPropertyEquipServiceClient.updatePropertyEquip(equipAddDTO);
            return new MessageVO(equipAddDTO.getDeviceUnique(),BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【物业_系统_设备管理】更新设备失败", e);
        }
    }


    /**
     * <desc>
     * 根据设备唯一码查询设备归属地址，并精确到unitId
     * <desc/>
     *
     * @param deviceUnique 待查询的设备唯一码
     * @return 归属地精确到小区后的unitId集合
     * @author Biao.R
     * @createDate 2017/12/15
     */
    private Set<String> getEquipOldUnitId(String deviceUnique) {
        List<PropertyEquipAddressVO> oldEquipAddress = iPropertyEquipServiceClient.getEquipAddress(deviceUnique);
        Set<String> oldUnitIdSet = new HashSet<>();
        if (oldEquipAddress != null && !oldEquipAddress.isEmpty()) {
            List<String> oldBuildIdList = new ArrayList<>();
            for (PropertyEquipAddressVO oldAdress : oldEquipAddress) {
                List<PropertyProjectUnitSimpleInfoVO> units = oldAdress.getUnits();
                if (units != null && !units.isEmpty()) {
                    for (PropertyProjectUnitSimpleInfoVO unit : units) {
                        oldUnitIdSet.add(unit.getUnitId());
                    }
                } else {
                    oldBuildIdList.add(oldAdress.getBuildId());
                }
            }
            if (!oldBuildIdList.isEmpty()) {
                List<String> unitIdList = iPropertyUnitInfoServiceClient.getUnitIdInBuildIds(String.join(",", oldBuildIdList));
                oldUnitIdSet.addAll(unitIdList);
            }
        }
        return oldUnitIdSet;
    }

    /**
     * <desc>
     * 分页查询设备列表
     * <desc/>
     *
     * @param propertyEquipGetPageDTO 物业设备数据传输对象
     * @return MessageVO 标准格式化响应结果
     * @author Biao.R
     * @createDate 2017/9/25
     */
    @ResponseBody
    @AuthAccessRequired
    @PostMapping(path = "/getByPage")
    public Object getEquipByPage(PropertyEquipGetPageDTO propertyEquipGetPageDTO) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyEquipGetPageDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyEquipGetPageDTO.class, request);
            if (propertyEquipGetPageDTO == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            Page<PropertyEquipGetVO> page = iPropertyEquipServiceClient.getByPage(propertyEquipGetPageDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), page);
        } catch (Exception e) {
            throw new DataAccessException("【物业_系统_设备管理】分页查询失败", e);
        }
    }

    /**
     * <desc>
     * 根据参数精确查找设备
     * <desc/>
     *
     * @param propertyEquipGetDTO 设备查询DTO
     * @return MessageVO 标准格式化响应结果
     * @author Biao.R
     * @createDate 2017/9/26
     */
    @ResponseBody
    @PostMapping(path = "/getByDeviceUnique")
    public Object getByDeviceUnique(PropertyEquipGetDTO propertyEquipGetDTO) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyEquipGetDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyEquipGetDTO.class, request);
            if (propertyEquipGetDTO == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            String deviceUnique = propertyEquipGetDTO.getDeviceUnique();
            if (StringUtils.isBlank(deviceUnique)) {
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_DEVICEUNIQUE_NOT_NULL.getErrorCode());
            }
            PropertyEquipGetVO propertyEquipGetVO = iPropertyEquipServiceClient.getByDeviceUnique(deviceUnique);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), propertyEquipGetVO);
        } catch (Exception e) {
            throw new DataAccessException("【物业_系统_设备管理】参数查询失败", e);
        }
    }

    /**
     * <desc>
     * 根据设备机号或名称查找设备时否唯一
     * <desc/>
     *
     * @param propertyEquipGetDTO 设备唯一性查询DTO
     * @return MessageVO 标准格式化响应结果
     * @author Biao.R
     * @createDate 2017/10/11
     */
    @ResponseBody
    @PostMapping(path = "/checkEquip")
    public Object checkEquip(PropertyEquipGetDTO propertyEquipGetDTO) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyEquipGetDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyEquipGetDTO.class, request);
            if (propertyEquipGetDTO == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }

            if (StringUtils.isBlank(propertyEquipGetDTO.getDeviceUnique())) {
                //根据设备机号或名称查询时，需要判断设备类型
                Integer deviceType = propertyEquipGetDTO.getDeviceType();
                if (deviceType == null || PropertyEquipTypeEnum.getByEquipType(deviceType).getType() == -1) {
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_DEVICETYPE_IS_ILLEGAL.getErrorCode());
                }
            }

            String deviceId = propertyEquipGetDTO.getDeviceId();
            String deviceName = propertyEquipGetDTO.getDeviceName();
            if (StringUtils.isNotBlank(deviceId)) {
                propertyEquipGetDTO.setDeviceId(String.format("%04d", Integer.parseInt(deviceId)));
            }
            if (StringUtils.isNotEmpty(deviceName)) {
                propertyEquipGetDTO.setDeviceId(null);
            }
            List<PropertyEquipGetVO> equipList = iPropertyEquipServiceClient.checkEquip(propertyEquipGetDTO);
            int equipCount = equipList.size();
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("equipList", equipList);
            resultMap.put("equipCount", equipCount);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), resultMap);
        } catch (Exception e) {
            throw new DataAccessException("【物业_系统_设备管理】设备唯一性校验失败", e);
        }
    }


    /**
     * <desc>
     * 查询设备归属地址
     * <desc/>
     *
     * @param deviceUnique 设备唯一码
     * @return MessageVO 标准格式化响应结果
     * @author Biao.R
     * @createDate 2017/9/26
     */
    @ResponseBody
    @PostMapping(path = "/getEquipAddress")
    public Object getEquipAddress(String deviceUnique) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            deviceUnique = request.getAttribute("deviceUnique") == null ? null : request.getAttribute("deviceUnique").toString();
            if (StringUtils.isBlank(deviceUnique)) {
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_DEVICEUNIQUE_NOT_NULL.getErrorCode());
            }
            List<PropertyEquipAddressVO> equipAddrs = iPropertyEquipServiceClient.getEquipAddress(deviceUnique);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), equipAddrs);
        } catch (Exception e) {
            throw new DataAccessException("【物业_系统_设备管理】查询设备地址失败", e);
        }
    }

    /**
     * <desc>
     * 一键启用/禁用设备
     * <desc/>
     *
     * @param deviceUniques 设备唯一码集
     * @param status        是否启用  1-启用  2-禁用
     * @return MessageVO 标准格式化响应结果
     * @author Biao.R
     * @createDate 2017/9/28
     */
    @ResponseBody
    @PostMapping(path = "/banOrUse")
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.EQUIP_BANORUSE_INFO_LOG_DESC)
    public Object banOrUse(String deviceUniques, String status, String loginUserId, String projectId) throws IOException {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        deviceUniques = request.getAttribute("deviceUniques") == null ? null : request.getAttribute("deviceUniques").toString();
        status = request.getAttribute("status") == null ? null : request.getAttribute("status").toString();
        loginUserId = request.getAttribute("loginUserId") == null ? null : request.getAttribute("loginUserId").toString();
        projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
        if (StringUtils.isBlank(deviceUniques)) {
            return new MessageVO(PropertyErrorCodeEnum.EQUIP_DEVICEUNIQUE_NOT_NULL.getErrorCode());
        }
        PropertyCloudIntercomSaveDTO equipAddDTO = new PropertyCloudIntercomSaveDTO();
        try {
            String[] deviceUniqueArr = deviceUniques.split(",");
            Set<String> deviceUniqueSet = new HashSet<>();
            Set<String> unitIdSet = new HashSet<>();
            for (String deviceUnique : deviceUniqueArr) {
                PropertyEquipGetVO oldEquip = iPropertyEquipServiceClient.getByDeviceUnique(deviceUnique);
                if (!status.equals(oldEquip.getStatus().toString())) {
                    deviceUniqueSet.add(deviceUnique);
                    //状态发生变化，查询受影响的住户，最终找到受影响用户的地址
                    Set<String> equipOldUnitIds = this.getEquipOldUnitId(deviceUnique);
                    if (!equipOldUnitIds.isEmpty()) {
                        unitIdSet.addAll(equipOldUnitIds);
                    }
                }
            }

            if (!deviceUniqueSet.isEmpty()) {
                equipAddDTO.setDeviceUnique(String.join(",", deviceUniqueSet));
                equipAddDTO.setStatus(Integer.parseInt(status));
                //地址发生变化，将变化的地址存储的到定时任务表中
                if (!unitIdSet.isEmpty()) {
                    Date date = new Date();
                    TimeTaskAuthDeviceAddressInfoPO deviceAddrPO = new TimeTaskAuthDeviceAddressInfoPO(projectId, loginUserId, String.join(",", unitIdSet), DataStatusEnum.NORMAL.getType(), date, date);
                    deviceAddrPO.setDeviceUniques(String.join(",",deviceUniqueSet));
                    equipAddDTO.setTimeTaskAuthDeviceAddressInfoPO(deviceAddrPO);
                }else{
                    Date date = new Date();
                    TimeTaskAuthDeviceAddressInfoPO deviceAddrPO = new TimeTaskAuthDeviceAddressInfoPO(projectId, loginUserId, "", DataStatusEnum.NORMAL.getType(), date, date);
                    deviceAddrPO.setDeviceUniques(String.join(",",deviceUniqueSet));
                    equipAddDTO.setTimeTaskAuthDeviceAddressInfoPO(deviceAddrPO);
                }
                iPropertyEquipServiceClient.updateStatus(equipAddDTO);
            }
        } catch (Exception e) {
            throw new DataAccessException("【物业_系统_设备管理】启用/禁用设备失败", e);
        }
        return new MessageVO(deviceUniques,BaseErrorCodeEnum.SUCCESS.getErrorCode());
    }


    /**
     * <desc>
     * 删除楼栋或单元地址时，解绑设备和地址的关系
     * <desc/>
     *
     * @param propertyProjectRemoveUnitInfoDTO 删除单元信息数据传输对象
     * @return MessageVO 标准格式化响应结果
     * @author Biao.R
     * @createDate 2017/9/28
     */
    @ResponseBody
    @PostMapping(path = "/deleteAddress")
    @LoggerInfo(operateDesc = LogDescConstant.EQUIP_DELETEADDRESS_INFO_LOG_DESC)
    public Object deleteAddress(PropertyProjectRemoveUnitInfoDTO propertyProjectRemoveUnitInfoDTO) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyProjectRemoveUnitInfoDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyProjectRemoveUnitInfoDTO.class, request);
            if (propertyProjectRemoveUnitInfoDTO == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            Integer result = iPropertyEquipServiceClient.deleteAddress(propertyProjectRemoveUnitInfoDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), result);
        } catch (Exception e) {
            throw new DataAccessException("【物业_系统_设备管理】解绑设备归属地址失败", e);
        }
    }

    /**
     * <desc>
     * 根据地址查询云对讲信息
     * <desc/>
     *
     * @param propertyEquipAuthGetDTO 地址查询DTO
     * @return MessageVO 标准格式化响应结果
     * @author Biao.R
     * @createDate 2017/10/09
     */
    @ResponseBody
    @PostMapping(path = "/getCloudIntercomByAddr")
    public Object getCloudIntercomByAddr(PropertyEquipAuthGetDTO propertyEquipAuthGetDTO) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyEquipAuthGetDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyEquipAuthGetDTO.class, request);
            if (propertyEquipAuthGetDTO == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            List<DeviceCloudIntercomSimpleVO> cloudIntercomSimpleVOS = iPropertyEquipServiceClient.getCloudIntercomByAddr(propertyEquipAuthGetDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), cloudIntercomSimpleVOS);
        } catch (Exception e) {
            throw new DataAccessException("【物业_系统_设备管理】查询设备数量失败", e);
        }

    }

    /**
     * <desc>
     * 绑定设权限时分页查询设备
     * <desc/>
     *
     * @param propertyEquipAuthGetDTO 设备类型
     * @return MessageVO 标准格式化响应结果
     * @author Biao.R
     * @createDate 2017/10/09
     */
    @ResponseBody
    @PostMapping(path = "/getEquipAuthByPage")
    @AuthAccessRequired
    public Object getEquipAuthByPage(PropertyEquipAuthGetDTO propertyEquipAuthGetDTO) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyEquipAuthGetDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyEquipAuthGetDTO.class, request);
            if (propertyEquipAuthGetDTO == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }

            PropertyEquipTypeEnum equipTypeEnum = PropertyEquipTypeEnum.getByEquipType(propertyEquipAuthGetDTO.getDeviceType());
            if (equipTypeEnum.getType() == -1) {
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_DEVICETYPE_IS_ILLEGAL.getErrorCode());
            }

            Page<PropertyEquipSimpleVO> result = iPropertyEquipServiceClient.getEquipAuthByPage(propertyEquipAuthGetDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), result);
        } catch (Exception e) {
            throw new DataAccessException("【物业_系统_设备管理】绑定设备权限时查询设备失败", e);
        }
    }

    /**
     * <desc>
     * 在数据字典中根据类型获取值和名称
     * </desc>
     *
     * @param codeType 类型
     * @return
     * @author zhangs
     * @createDate 2017/10/18
     */
    @ResponseBody
    @PostMapping(path = "/getDataDictionary")
    public Object getDataDictionary(String codeType, String projectId) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            codeType = request.getAttribute("codeType") == null ? null : request.getAttribute("codeType").toString();
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            if (StringUtils.isBlank(codeType)) {
                return new MessageVO(PropertyErrorCodeEnum.PUB_DATADICTIONARY_CODETYPE_EMPTY_ERR.getErrorCode());
            }

            List<SysCodePO> sysCodePOS = iDataDictionaryServiceClient.getDataDictionary(codeType);
            //查询设备类型时，需要根据项目是否启用云对讲来判断是否返回云对讲类型
            if ("device_type".equals(codeType.trim()) && StringUtils.isNotEmpty(projectId)) {
                Integer isSmartCommunity = iOperateProjectServiceClient.getIsSmartCommunity(projectId);
                if (sysCodePOS != null && !sysCodePOS.isEmpty() && isSmartCommunity != ProjectSmartCommunityStatusEnum.PROJECT_SMART_COMMUNITY_YES.getType()) {
                    Iterator<SysCodePO> iterator = sysCodePOS.iterator();
                    while (iterator.hasNext()) {
                        SysCodePO sysCodePO = iterator.next();
                        //没有启用云对讲的小区需要移除云对讲类型
                        if ((PropertyEquipTypeEnum.CLOUD_INTERCOM.getType().toString()).equals(sysCodePO.getCodeValue())) {
                            iterator.remove();
                        }
                    }
                }
            }
            //根据项目配置的住宅 办公类型而定返回的房屋类型
            if ("room_type".equals(codeType.trim()) && StringUtils.isNotEmpty(projectId)) {
                String projectType = iOperateProjectServiceClient.getProjectType(projectId);
                if (sysCodePOS != null && !sysCodePOS.isEmpty()) {
                    Iterator<SysCodePO> iterator = sysCodePOS.iterator();
                    while (iterator.hasNext()) {
                        SysCodePO sysCodePO = iterator.next();
                        if(projectType.contains("1") && projectType.contains("2")){
                            break;
                        }else if(projectType.equals("1")){
                            if(sysCodePO.getCodeValue().equals("3")){
                                iterator.remove();
                            }
                        }else if(projectType.equals("2")){
                            if(sysCodePO.getCodeValue().equals("1")){
                                iterator.remove();
                            }
                        }
                    }
                }
            }

            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), sysCodePOS);
        } catch (Exception e) {
            throw new DataAccessException(String.format("【物业系统_查询数据字典_getDataDictionary()】info:{%s}", codeType), e);
        }
    }


    /**
     * <desc>
     * 查询单个项目的关联设备列表
     * <desc/>
     *
     * @param projectId 项目编号
     * @return
     * @author Chunjian.G
     * @createDate 2017-10-13
     */
    @PostMapping(value = "/getProjectProduct")
    @ResponseBody
    public Object getRelatedProducts(String projectId) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            //参数判断
            if (StringUtils.isBlank(projectId)) {
                return new MessageVO(OperateErrorCodeEnum.PROJECT_ID_INVALID_ERR.getErrorCode());
            }
            List<OperateProjectRelatedProductVO> productVOS = iOperateProjectServiceClient.getRelatedProducts(projectId);
            List<Map<String, Object>> result = new ArrayList<>();
            if (productVOS != null && !productVOS.isEmpty()) {
                for (OperateProjectRelatedProductVO productVO : productVOS) {
                    if (productVO.getDeviceKind() == PropertyEquipTypeEnum.CLOUD_INTERCOM.getType()) {
                        Map<String, Object> resultMap = new HashMap<>();
                        resultMap.put("productTypeId", productVO.getTypePid());
                        resultMap.put("productTypeName", productVO.getTypeCode());
                        result.add(resultMap);
                    }
                }
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), result);
        } catch (Exception e) {
            throw new DataAccessException("【物业_设备管理_getRelatedProducts】查询小区产品型号", e);
        }
    }


    /**
     * <desc>
     * 对云对讲相关的预处理
     * <desc/>
     *
     * @param cloudIntercomSaveDTO 处理前的数据传输对象
     * @return PropertyEquipSaveDTO    处理后的数据传输对象
     * @author Biao.R
     * @createDate 2017/10/9
     */
    private PropertyCloudIntercomSaveDTO cloudIntercomeHandle(PropertyCloudIntercomSaveDTO cloudIntercomSaveDTO) throws Exception {

        //拼接sn
        String[] buildIdArr = null;
        String[] unitIdArr = null;
        String buildIds = cloudIntercomSaveDTO.getBuildIds();
        String unitIds = cloudIntercomSaveDTO.getUnitIds();
        if (StringUtils.isNotEmpty(buildIds)) {
            buildIdArr = buildIds.split(",");
        }
        if (StringUtils.isNotEmpty(unitIds)) {
            unitIdArr = unitIds.split(",");
        }
        String buildNum = "000";
        String unitNum = "00";
        String projectId = cloudIntercomSaveDTO.getProjectId();

        //围墙机的SN后面buildNum和unitNum 全为0,门口机分情况考虑
        if (cloudIntercomSaveDTO.getSmartType() == PropertyEquipTypeEnum.CLOUD_INTERCOM_ENTRANCE.getType()) {
            if (unitIdArr != null && unitIdArr.length == 1) {
                PropertyProjectGetUnitInfoDTO unitDTO = new PropertyProjectGetUnitInfoDTO(unitIds);
                PropertyProjectUnitInfoVO oneUnitInfo = iPropertyUnitInfoServiceClient.getOneUnitInfo(unitDTO);
                if (oneUnitInfo != null) {
                    unitNum = oneUnitInfo.getUnitNum();
                    buildNum = oneUnitInfo.getBuildNum();
                }
            }
            if ("000".equals(buildNum) && buildIdArr != null && buildIdArr.length == 1) {
                PropertyProjectGetBuildInfoDTO buildDTO = new PropertyProjectGetBuildInfoDTO(buildIds);
                PropertyProjectBuildInfoVO oneBuildInfo = iPropertyBuildInfoServiceClient.getOneBuildInfo(buildDTO);
                if (null != oneBuildInfo) {
                    buildNum = oneBuildInfo.getBuildNum();
                }
            }
        }
        if(PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType() == cloudIntercomSaveDTO.getElevatorType()){
            cloudIntercomSaveDTO.setSn(String.format("%s%s%03d", cloudIntercomSaveDTO.getProjectId(), "00000", Integer.parseInt(cloudIntercomSaveDTO.getDeviceId())));
        }else if(PropertyEquipTypeEnum.ENTRANCE.getType() == cloudIntercomSaveDTO.getDeviceType()){
            cloudIntercomSaveDTO.setSn(String.format("%s%s%04d", cloudIntercomSaveDTO.getProjectId(), "0000", Integer.parseInt(cloudIntercomSaveDTO.getDeviceId())));
        }else{
            cloudIntercomSaveDTO.setSn(String.format("%s%s%s%03d", cloudIntercomSaveDTO.getProjectId(), buildNum, unitNum, Integer.parseInt(cloudIntercomSaveDTO.getDeviceId())));
        }
        //查找产品类型
        /*OperateProductTypeDetailVO product = iOperateProductTypeServiceClient.getDetail(cloudIntercomSaveDTO.getProductTypeId());
        cloudIntercomSaveDTO.setSignSecretKey(product.getSignSecretKey());
        cloudIntercomSaveDTO.setSignPubKey(product.getSignPubKey());*/
        return cloudIntercomSaveDTO;
    }


    /**
     * <desc>
     * 抽取添加和更新设备时校验:设备类型，机号范围，设备归属地个数
     * <desc/>
     *
     * @param propertyEquipSaveDTO 物业设备数据传输对象
     * @return 标准格式化响应结果
     * @author Biao.R
     * @createDate 2017/10/11
     */
    private MessageVO saveAndUpdateCheck(PropertyEquipSaveDTO propertyEquipSaveDTO) throws Exception {

        if (propertyEquipSaveDTO == null) {
            return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
        }
//        ProjectPO oneProject = iOperateProjectServiceClient.getOneProject(propertyEquipSaveDTO.getProjectId());
        if (!NumberHandlerUtil.isInRange(propertyEquipSaveDTO.getEquipMode(), 1, 2)/* || (propertyEquipSaveDTO.getEquipMode() == 2 && oneProject.getChargeMode() == 1)*/) {
            return new MessageVO(PropertyErrorCodeEnum.EQUIP_CHARGE_MODE_ERR.getErrorCode());
        }
        Integer deviceType = propertyEquipSaveDTO.getDeviceType();

        Integer deviceId = propertyEquipSaveDTO.getDeviceId();


        String[] buildIdArr = null;
        String[] unitIdArr = null;
        String buildIds = propertyEquipSaveDTO.getBuildIds();
        String unitIds = propertyEquipSaveDTO.getUnitIds();
        if (StringUtils.isNotEmpty(buildIds)) {
            buildIdArr = buildIds.split(",");
            //楼栋ID去重
            HashSet<String> buildIdSet = new HashSet<>(Arrays.asList(buildIdArr));
            propertyEquipSaveDTO.setBuildIds(String.join(",", buildIdSet));
        }
        if (StringUtils.isNotEmpty(unitIds)) {
            unitIdArr = unitIds.split(",");
            //单元ID去重
            HashSet<String> unitIdSet = new HashSet<>(Arrays.asList(unitIdArr));
            propertyEquipSaveDTO.setUnitIds(String.join(",", unitIdSet));
        }

            if (buildIdArr == null && propertyEquipSaveDTO.getEntranceType()!=EntranceTypeEnum.COMMON_ENTRANCE.getType()) {
            return new MessageVO(PropertyErrorCodeEnum.EQUIP_SERVER_ADDR_IS_ILLEGAL.getErrorCode());
        }

        //设备类型及设备机号范围校验
        switch (PropertyEquipTypeEnum.getByEquipType(deviceType)) {
            case ELEVATOR:
                //电梯机号范围判断
                if (!NumberHandlerUtil.isInRange(deviceId, 1, PlatformConstants.MAX_ELEVATOR_DEVICEID)) {
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_ELEVATOR_DEVICEID_OUT_RANGE.getErrorCode());
                }

                if (!(buildIdArr != null && buildIdArr.length == 1 && unitIdArr != null && unitIdArr.length > 0)) {
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_SERVER_ADDR_IS_ILLEGAL.getErrorCode());
                }
                if(propertyEquipSaveDTO.getElevatorType()!=PropertyEquipTypeEnum.BLUETOOTH_CALL.getType()) {
                    //电梯需判断服务楼层总数
                    Integer floorNo = propertyEquipSaveDTO.getFloorNo();
                    Integer floorNoMax = propertyEquipSaveDTO.getFloorNoMax();
                    if (floorNo == null || floorNoMax == null) {
                        return new MessageVO(PropertyErrorCodeEnum.EQUIP_ELEVATORFLOOR_NOT_NULL.getErrorCode());
                    }
                    if (floorNo > floorNoMax) {
                        return new MessageVO(PropertyErrorCodeEnum.EQUIP_ELEVATOR_FLOOR_IS_ILLEGAL.getErrorCode());
                    }
                    if ((floorNoMax - floorNo + 1) > PlatformConstants.MAX_ELEVATOR_FLOORNUM) {
                        //电梯服务的总楼层数不能大于控制段子数：112
                        return new MessageVO(PropertyErrorCodeEnum.EQUIP_ELEVATORFLOOR_OUT_RANGE.getErrorCode());
                    }
                }
                break;
            case ENTRANCE:

                //门禁机号范围校验
                if (!NumberHandlerUtil.isInRange(deviceId, 1, PlatformConstants.MAX_ENTRANCE_DEVICEID)) {
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_ENTRANCE_DEVICEID_OUT_RANGE.getErrorCode());
                }
                //门禁分1栋多单元和多栋
//                if (!(buildIdArr != null && ((unitIdArr != null && buildIdArr.length == 1) || (buildIdArr.length > 1 && unitIdArr == null)))) {
//                    if(propertyEquipSaveDTO.getEntranceType()!=EntranceTypeEnum.COMMON_ENTRANCE.getType()){
//                        return new MessageVO(PropertyErrorCodeEnum.EQUIP_SERVER_ADDR_IS_ILLEGAL.getErrorCode());
//                    }
//                }
                break;
            case CLOUD_INTERCOM:

                //云对讲机号范围校验
                if (!NumberHandlerUtil.isInRange(deviceId, 1, PlatformConstants.MAX_CLOUD_INTERCOM_DEVICEID)) {
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_CLOUDINTERCOM_DEVICEID_OUT_RANGE.getErrorCode());
                }

                //云对讲类型校验
                Integer smartType = propertyEquipSaveDTO.getSmartType();
                if (!(PropertyEquipTypeEnum.getByEquipType(smartType).getType() != -1 && smartType.toString().startsWith("3"))) {
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_SERVER_ADDR_IS_ILLEGAL.getErrorCode());
                }

                //围墙机多栋，门口机分1栋多单元和多栋
                if (!(buildIdArr != null && (buildIdArr != null && buildIdArr.length >= 1 && unitIdArr == null) || ((unitIdArr != null && buildIdArr.length == 1) && PropertyEquipTypeEnum.CLOUD_INTERCOM_ENTRANCE.getType() == smartType))) {
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_SERVER_ADDR_IS_ILLEGAL.getErrorCode());
                }
                //云对讲设备其他参数预处理
                break;
            default:
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_DEVICETYPE_IS_ILLEGAL.getErrorCode());
        }
        //一栋多单元时，需要校验添加的单元都是该楼栋下的
        if(propertyEquipSaveDTO.getEntranceType()!=EntranceTypeEnum.COMMON_ENTRANCE.getType() ){
            if (buildIdArr.length == 1 && (unitIdArr != null && unitIdArr.length > 0)) {
                List<String> unitIdList = iPropertyUnitInfoServiceClient.getUnitIdInBuildIds(buildIdArr[0]);
                if (unitIdList == null || unitIdList.isEmpty() || !unitIdList.containsAll(Arrays.asList(unitIdArr))) {
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_ADDRESS_MAP_IS_ILLEGAL.getErrorCode());
                }
            }
        }
        return null;
    }


    /**
     * <desc>
     * 判断当前项目是否启用了云对讲
     * <desc/>
     *
     * @param projectId  当前操作的小区编号
     * @param moduleType 魔魁啊类型
     * @return 标准格式化响应结果
     * @author Biao.R
     * @createDate 2017/12/19
     */
    @ResponseBody
    @PostMapping(path = "/checkIsSmartCommunity")
    public Object checkIsSmartCommunity(String projectId, Integer moduleType) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            moduleType = request.getAttribute("moduleType") == null ? null : (Integer) request.getAttribute("moduleType");
            if (StringUtils.isEmpty(projectId)) {
                return new MessageVO(PropertyErrorCodeEnum.PUB_PROJECT_ID_IS_ILLEGAL.getErrorCode());
            }
            List<SysCodePO> sysCodePOS = iDataDictionaryServiceClient.getDataDictionary("device_type");
            //查询设备类型时，需要根据项目是否启用云对讲来判断是否返回云对讲类型
            Integer isSmartCommunity = iOperateProjectServiceClient.getIsSmartCommunity(projectId);

            if (moduleType != null && isSmartCommunity == 0) {
                //设备模块和通行纪录，需要查询有没有相应纪录，如果有，则需要显示
                switch (CloudIntercomFunctionModuleEnum.getByType(moduleType)) {
                    case EQUIP_MODULE:
                        Integer equipCount = iPropertyEquipServiceClient.countCloudEquipByProjectId(projectId);
                        if (equipCount > 0) {
                            isSmartCommunity = ProjectSmartCommunityStatusEnum.PROJECT_SMART_COMMUNITY_YES.getType();
                        }
                        break;
                    case EQUIPRECORD_MODULE:
                        Integer recordCount = iPropertyEquipRecordServiceClient.countCloudRecordByProjectId(projectId);
                        if (recordCount > 0) {
                            isSmartCommunity = ProjectSmartCommunityStatusEnum.PROJECT_SMART_COMMUNITY_YES.getType();
                        }
                        break;
                }
            }
            //根据是否显示云对讲来去掉从字典表中获取的数据
            if (sysCodePOS != null && !sysCodePOS.isEmpty() && isSmartCommunity != ProjectSmartCommunityStatusEnum.PROJECT_SMART_COMMUNITY_YES.getType()) {
                Iterator<SysCodePO> iterator = sysCodePOS.iterator();
                while (iterator.hasNext()) {
                    SysCodePO sysCodePO = iterator.next();
                    //没有启用云对讲的小区需要移除云对讲类型
                    if ((PropertyEquipTypeEnum.CLOUD_INTERCOM.getType().toString()).equals(sysCodePO.getCodeValue())) {
                        iterator.remove();
                    }
                }
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), sysCodePOS);

        } catch (Exception e) {
            throw new DataAccessException("【物业系统_查询设备类型_checkIsSmartCommunity】查询项目是否启用云对讲失败", e);
        }
    }

    /**
     * <desc>
     *  判断当前项目是否启用了蓝牙和云电梯
     * <desc/>
     *
     * @param projectId  当前操作的小区编号
     * @return 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2018/04/19
     */
    @ResponseBody
    @RequestMapping(path= "/checkIsCloudOrBluetoothElevator")
    public Object checkIsCloudOrBluetoothElevator(String projectId){
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            if(StringUtils.isEmpty(projectId)){
                return new MessageVO(PropertyErrorCodeEnum.PUB_PROJECT_ID_IS_ILLEGAL.getErrorCode());
            }
            //该项目是否启用云电梯设备
            Map<String,Integer> isCloudElevator = iOperateProjectServiceClient.getIsCloudElevator(projectId);

            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),isCloudElevator);

        } catch (Exception e) {
            throw new DataAccessException("【物业系统_查询设备类型_checkIsCloudOrBluetoothElevator】查询项目是否启用云电梯和蓝牙失败", e);
        }
    }

    /**
     * <desc>
     * 设置云对讲设备的待机界面-只针对新的安卓版云对讲设备
     * <desc/>
     *
     * @param deviceUniqueStr 云对讲设备的deviceUnique号，多个以逗号隔开
     * @return 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2018/08/07
     */
    @ResponseBody
    @LoggerInfo(operateDesc = LogDescConstant.CLOUD_INTERCOM_STAND_BY_LOG_DESC)
    @RequestMapping(path = "/setStandbyInterface")
    public Object setStandbyInterface(String deviceUniqueStr,String fileUrl) {

        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            deviceUniqueStr = request.getAttribute("deviceUniqueStr") == null ? null : request.getAttribute("deviceUniqueStr").toString();
            fileUrl = request.getAttribute("fileUrl") == null ? null : request.getAttribute("fileUrl").toString();
            if(StringUtils.isEmpty(deviceUniqueStr)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            iPropertyEquipServiceClient.setStandbyInterface(deviceUniqueStr,fileUrl);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【物业系统_setStandbyInterface】设置云对讲设备的待机界面失败", e);
        }
    }

    /**
     * <desc>
     * 修改电梯设备的楼层映射表
     * <desc/>
     *
     * @param deviceUniqueStr 电梯设备的deviceUnique号
     * @return 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2018/08/21
     */
    @ResponseBody
    @LoggerInfo(operateDesc = LogDescConstant.DEVICE_ELEVATOR_FLOOR_CONFIG_UPDATE_LOG_DESC)
    @RequestMapping(path = "/updateFloorInfo")
    public Object updateFloorInfo(String deviceUniqueStr,String updateFloorInfoStr,String projectId,Integer bracketPanel){

        try{
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            deviceUniqueStr = request.getAttribute("deviceUniqueStr") == null ? null : request.getAttribute("deviceUniqueStr").toString();
            updateFloorInfoStr = request.getAttribute("updateFloorInfoStr") == null ? null : request.getAttribute("updateFloorInfoStr").toString();
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            bracketPanel = request.getAttribute("bracketPanel") == null ? 0 : (Integer) request.getAttribute("bracketPanel");
            if(StringUtils.isEmpty(deviceUniqueStr) || StringUtils.isEmpty(projectId)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if(StringUtils.isEmpty(updateFloorInfoStr)){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_ELEVATOR_FLOOR_INFO_EMPTY.getErrorCode());
            }
            //解析JSON数据
            List<ElevatorFloorInfoDTO> list;
            try {
                list = JSON.parseArray(updateFloorInfoStr, ElevatorFloorInfoDTO.class);
            } catch (Exception e) {
                throw new DataAccessException("【物业系统_updateFloorInfo】修改电梯设备的楼层映射表数据格式有误", e);
            }
            Map<String,Object> resultMap = iPropertyEquipServiceClient.updateFloorInfo(deviceUniqueStr, list, projectId, bracketPanel);
            // 云对讲SDK的内容，rebase时候要留着，不要删掉，有疑问找老汪
            this.updateToUrl(deviceUniqueStr,projectId);
            //查询当前项目信息
            ProjectPO projectPO = iOperateProjectServiceClient.getOneProject(projectId);
            // 平板优先离线，则插入同步数据
            if (projectPO.getOnOffLinePadFace() != null) {
                PadFaceSyncDataDTO padFaceSyncDataDTO = new PadFaceSyncDataDTO();
                padFaceSyncDataDTO.setOperateType("2");
                padFaceSyncDataDTO.setDeviceUniques(deviceUniqueStr);
                padFaceSyncDataDTO.setProjectId(projectId);
                padFaceSyncDataDTO.setStatus("1");
                padFaceSyncDataDTO.setSourceSystem(2);
                if(projectPO.getOnOffLinePadFace() == 1){
                    iPadFaceSyncDataServiceClient.userOrFloorSync(padFaceSyncDataDTO);
                }
                iPadFaceSyncDataServiceClient.userOrFloorSyncSmartCard(padFaceSyncDataDTO);
            }
            return new MessageVO(deviceUniqueStr,BaseErrorCodeEnum.SUCCESS.getErrorCode(),resultMap);
        }catch (Exception e){
            throw new DataAccessException("【物业系统_updateFloorInfo】修改电梯设备的楼层映射表失败",e);
        }
    }

    /**
     * <desc>
     *      快速设置楼层映射表
     * </desc>
     *
     * @param startFloor    开始权限标识号
     * @param startTerminal 开始端子号
     * @param deviceUnique 设备序列号
     * @param type 1端子号 2检测楼层 3按键名称
     * @return
     * @author Jiaqi.X
     * @createDate 2018/11/26
     */
    @ResponseBody
    @LoggerInfo(operateDesc = LogDescConstant.DEVICE_ELEVATOR_FLOOR_FAST_SETTING_LOG_DESC)
    @RequestMapping(path = "/floorsFastSetting")
    public Object floorsFastSetting(String startFloor,String endFloor,String startTerminal,String deviceUnique,Integer type){

        try{
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            startFloor = request.getAttribute("startFloor") == null ? null : request.getAttribute(startFloor).toString();
            endFloor = request.getAttribute("endFloor") == null ? null : request.getAttribute("endFloor").toString();
            startTerminal = request.getAttribute("startTerminal") == null ? null : request.getAttribute("startTerminal").toString();
            deviceUnique = request.getAttribute("deviceUnique") == null ? null : request.getAttribute("deviceUnique").toString();
            type = request.getAttribute("type") == null ? null : (Integer) request.getAttribute("type");
            if(StringUtils.isEmpty(deviceUnique) || StringUtils.isEmpty(deviceUnique)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            iPropertyEquipServiceClient.floorFastSetting(startFloor,endFloor, startTerminal,deviceUnique,type);
            return new MessageVO(deviceUnique,BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch (Exception e){
            throw new DataAccessException("【物业系统_floorsFastSetting】快速设置楼层映射表失败",e);
        }
    }

    /**
     * <desc>
     * 重置电梯设备的楼层映射表
     * <desc/>
     *
     * @param deviceUniqueStr 电梯设备的deviceUnique号，多个以逗号隔开
     * @return 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2018/08/21
     */
    @ResponseBody
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.DEVICE_ELEVATOR_FLOOR_RESET_LOG_DESC)
    @RequestMapping(path = "/resetFloorInfo")
    public Object resetFloorInfo(String deviceUniqueStr,String projectId){

        try{
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            deviceUniqueStr = request.getAttribute("deviceUniqueStr") == null ? null : request.getAttribute("deviceUniqueStr").toString();
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            if(StringUtils.isEmpty(deviceUniqueStr) || StringUtils.isEmpty(projectId)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            iPropertyEquipServiceClient.resetFloorInfo(deviceUniqueStr,projectId);
            // 云对讲SDK的内容，rebase时候要留着，不要删掉，有疑问找老汪
            this.updateToUrl(deviceUniqueStr,projectId);
            //查询当前项目信息
            ProjectPO projectPO = iOperateProjectServiceClient.getOneProject(projectId);
            // 平板优先离线，则插入同步数据
            if (projectPO.getOnOffLinePadFace() != null) {
                PadFaceSyncDataDTO padFaceSyncDataDTO = new PadFaceSyncDataDTO();
                padFaceSyncDataDTO.setOperateType("2");
                padFaceSyncDataDTO.setDeviceUniques(deviceUniqueStr);
                padFaceSyncDataDTO.setProjectId(projectId);
                padFaceSyncDataDTO.setStatus("1");
                padFaceSyncDataDTO.setSourceSystem(2);
                if(projectPO.getOnOffLinePadFace() == 1){
                    iPadFaceSyncDataServiceClient.userOrFloorSync(padFaceSyncDataDTO);
                }
                iPadFaceSyncDataServiceClient.userOrFloorSyncSmartCard(padFaceSyncDataDTO);
            }
            return new MessageVO(deviceUniqueStr,BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch (Exception e){
            throw new DataAccessException("【物业系统_resetFloorInfo】重置电梯设备的楼层映射表失败",e);
        }
    }

    /**
     * <desc>
     * 根据deviceUnique获取电梯设备的楼层映射信息
     * <desc/>
     *
     * @param deviceUniqueStr 电梯设备的deviceUnique号
     * @return 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2018/08/21
     */
    @ResponseBody
    @AuthAccessRequired
    @RequestMapping(path = "/getElevatorFloorInfo")
    public Object getElevatorFloorInfo(String deviceUniqueStr){
        try{
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            deviceUniqueStr = request.getAttribute("deviceUniqueStr") == null ? null : request.getAttribute("deviceUniqueStr").toString();
            if(StringUtils.isEmpty(deviceUniqueStr)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            List<CloudElevatorFloorInfoVO> list = iPropertyEquipServiceClient.getElevatorFloorInfo(deviceUniqueStr);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),list);
        }catch (Exception e){
            throw new DataAccessException("【物业系统_getElevatorFloorInfo】根据deviceUnique获取电梯设备的楼层映射信息失败",e);
        }
    }

    /**
     * <desc>
     *      获取电梯设备的可设置楼层
     * <desc/>
     *
     * @param buildId 楼栋id
     * @return 标准格式化响应结果
     * @author Jiaqi.X
     * @createDate 2018/12/18
     */
    @ResponseBody
    @RequestMapping(path = "/getBuildMaxFloorAndMinFloor")
    public Object getBuildMaxFloorAndMinFloor(String buildId){
        try{
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            buildId = request.getAttribute("buildId") == null ? null : request.getAttribute("buildId").toString();
            if(StringUtils.isEmpty(buildId)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),iPropertyEquipServiceClient.getBuildMaxFloorAndMinFloor(buildId));
        }catch (Exception e){
            throw new DataAccessException("【物业系统_getBuildMaxFloorAndMinFloor】获取电梯设备的可设置楼层信息失败",e);
        }
    }

    /**
     * <desc>
     *      处理设备旧数据的sip账号，为了便于灵云区分测试和正式sip故在测试环境设备账号前加184前缀
     * <desc/>
     *
     * @return 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2018/12/28
     */
    @ResponseBody
    @LoggerInfo(operateDesc = LogDescConstant.UPDATE_OLD_DEVICE_SIP_ACCOUNT_LOG_DESC)
    @RequestMapping(path = "/updateOldDeviceSipAccount")
    public Object updateOldDeviceSipAccount(){
        try{
            iPropertyEquipServiceClient.updateOldDeviceSipAccount();
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch (Exception e){
            throw new DataAccessException("【物业系统_updateOldDeviceSipAccount】处理设备旧数据的sip账号前缀失败",e);
        }
    }

    /**
     * <desc>
     *      获取最大权限标识及最小权限标识
     * </desc>
     *
     * @param deviceUnique
     * @return
     * @author Jiaqi.X
     * @createDate 2018/12/18
     */
    @ResponseBody
    @RequestMapping(path = "/getMaxNaturalAndMinNatural")
    public Object getMaxNaturalAndMinNatural(String deviceUnique){
        try{
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            deviceUnique = request.getAttribute("deviceUnique") == null ? null : request.getAttribute("deviceUnique").toString();
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),iPropertyEquipServiceClient.getMaxNaturalAndMinNatural(deviceUnique));
        }catch (Exception e){
            throw new DataAccessException("【物业系统_getMaxNaturalAndMinNatural】获取最大权限标识及最小权限标识失败",e);
        }
    }

    /**
     * <desc>
     *      云电梯SDK第三方云端上报设备信息变更后接口数据结构说明
     * </desc>
     *
     * @param deviceUniqueStr 设备序列号，多个英文逗号相连
     * @param projectId 项目id
     * @author wangzhi
     * @createDate 2019/01/21
     */
    private void updateToUrl(String deviceUniqueStr,String projectId){
        new Thread(() -> {
            try {
                List<String> deviceUniqueList = StringHandlerUtil.splitStringList(deviceUniqueStr);
                SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
                Date date = new Date();
                String createTime = df.format(date);//签名用时间
                List<PropertyRoleProjectGetVO> propertyRoleProjectGetVOS = iOperateProjectServiceClient.getRoleProjectInfo(projectId);
                if (propertyRoleProjectGetVOS == null || propertyRoleProjectGetVOS.isEmpty()) {
                    return;
                }
                for (PropertyRoleProjectGetVO propertyRoleProjectGetVO : propertyRoleProjectGetVOS) {
                    if (propertyRoleProjectGetVO == null || StringUtils.isBlank(propertyRoleProjectGetVO.getUpdateInfoUrl())
                            || StringUtils.isBlank(propertyRoleProjectGetVO.getAppSecret()) || StringUtils.isBlank(propertyRoleProjectGetVO.getAppId())) {
                        continue;
                    }
                    URL url = new URL(propertyRoleProjectGetVO.getUpdateInfoUrl());
                    //打开url连接
                    HttpURLConnection con = (HttpURLConnection) url.openConnection();
                    //获取链接后的状态值
                    int state = con.getResponseCode();
                    if (state != 200) {
                        continue;
                    }
                    for (String deviceUnique : deviceUniqueList){
                        PropertyDeviceElevatorConfigVO propertyDeviceElevatorConfigVO = iPropertyEquipServiceClient.getDeviceElevatorConfig(deviceUnique);
                        if (propertyDeviceElevatorConfigVO == null || StringUtils.isBlank(propertyDeviceElevatorConfigVO.getDeviceUnique())) {
                            continue;
                        }
                        JSONObject json = new JSONObject();
                        json.put("deviceUnique", propertyDeviceElevatorConfigVO.getDeviceUnique());
                        json.put("logicalFloor ", propertyDeviceElevatorConfigVO.getLogicalFloor());
                        json.put("floorNum", propertyDeviceElevatorConfigVO.getFloorNum());
                        Map<String, Object> jsonToMap = JsonUtil.JsonToMap(json.toJSONString());
                        String sign = Md5EncryptUtil.cloudDeviceMd5(jsonToMap, createTime, propertyRoleProjectGetVO.getAppSecret());
                        //LOG.info(deviceUnique + "的sign：" + sign);
                        // 加密前先将createTime传入方法,最后在将createTime和sign放入json中
                        json.put("createTime", createTime);
                        json.put("sign", sign);
                        //LOG.info(deviceUnique + "加密前的参数：" + json);
                        String encryptResult = DesEncryptUtil.aesEncryptSDK(json.toJSONString(), propertyRoleProjectGetVO.getAppSecret());
                        //LOG.info(deviceUnique + "加密后的参数：" + encryptResult);
                        String encryptReturn = HttpProtocolUtil.httpPost(propertyRoleProjectGetVO.getUpdateInfoUrl(), "encryptScript=" + encryptResult);
                        String result = DesEncryptUtil.aesDecrypt(encryptReturn, propertyRoleProjectGetVO.getAppSecret());
                        // 处理结果：0正常 1错误
                        JSONObject jsonObject = JSON.parseObject(result);
                        if ("0".equals(jsonObject.getString("result"))) {
                            //LOG.info(deviceUnique + "上报成功，返回值为：" + result);
                        } else {
                            LOG.info(deviceUnique + "上报失败，返回值为：" + result);
                        }
                    }
                }
            } catch (Exception e) {
                LOG.error("【第三方云端上报设备信息(楼层映射表信息)变更后接口数据结构说明失败】",e);
            }
        }).start();
    }

    /**
     * <desc>
     *      调整电梯楼层范围
     * </desc>
     *
     * @return
     * @author Jiaqi.X
     * @createDate 2019/03/27
     */
    @ResponseBody
    @RequestMapping(path = "/floorMappingTrim")
    public Object floorMappingTrim(){
        try{
            iPropertyEquipServiceClient.floorMappingTrim();
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch (Exception e){
            throw new DataAccessException("【物业系统_floorMappingTrim】调整电梯楼层范围失败",e);
        }
    }

    /**
     * <desc>
     *     兼容之前添加门禁设备的门禁类别
     * </desc>
     *
     * @author Juguang.S
     * @createDate 2019/02/21
     */
    @ResponseBody
    @LoggerInfo(operateDesc = LogDescConstant.HANDLER_OLD_DATA_ENTRANCE_TYPE_LOG_DESC)
    @PostMapping(path ="/handleOldDataEntranceTypeInfo")
    public Object handleOldDataEntranceType(){
        try {
            iPropertyEquipServiceClient.handleOldDataEntranceType();
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【物业系统_handleOldDataEntranceType】兼容之前添加门禁设备的门禁类别",e);
        }
    }

    /**
     * <desc>
     *      获取不同设备的批次号。
     * <desc/>
     *
     * @param  projectId 项目ID
     * @param  deviceType 设备类型1-电梯 2-门禁 3-云对讲 4-平板
     * @return
     * @author Juguang.S
     * @createDate 2019-11-21
     */
    @ResponseBody
    @RequestMapping(path = "/getBatchNumber" , method = RequestMethod.POST)
    public Object getBatchNumber(String projectId,String deviceType) {
        try{
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            deviceType = request.getAttribute("deviceType") == null ? null : request.getAttribute("deviceType").toString();
            if(StringUtils.isEmpty(projectId) || StringUtils.isEmpty(deviceType)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            List<String> str= iPropertyEquipServiceClient.getBatchNumber(projectId,deviceType);
            Map<String,Object> resultMap = new HashMap<>();
            resultMap.put("batchNumberList",str);

            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),str);
        }catch (Exception e){
            throw new DataAccessException("【物业_获取不同设备的批次号】失败",e);
        }
    }

    /**
     * <desc>
     *      获取设备扫码开门的二维码
     * </desc>
     *
     * @author wangzhi
     * @createDate 2019/12/10
     */
    @UnAuthAccessRequired
    @UnParamEncrypt
    @ResponseBody
    @PostMapping(path = "/getOpenEquipQrCode")
    public Object getOpenEquipQrCode() {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            PropertyEquipGetPageDTO propertyEquipGetPageDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyEquipGetPageDTO.class, request);
            if (propertyEquipGetPageDTO == null || StringUtils.isBlank(propertyEquipGetPageDTO.getDeviceUnique())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            // 二维码的内容
            String htmlUrl = "https://develop.wx.jia-r.com/device" + "?deviceUnique=" + propertyEquipGetPageDTO.getDeviceUnique() + "&deviceName=" + propertyEquipGetPageDTO.getDeviceName();
            // 生成二维码
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            BufferedImage bim = QrcodeUtils.getQR_CODEBufferedImage(htmlUrl, BarcodeFormat.QR_CODE, 300, 300, QrcodeUtils.getDecodeHintType());
            ImageIO.write(bim, "jpg", os);
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(os.toByteArray());
            String qrCodeUrl = this.uploadFile(byteArrayInputStream);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), (Object) qrCodeUrl);
        } catch (Exception e) {
            throw new DataAccessException("【物业系统_getOpenEquipQrCode】获取设备扫码开门的二维码失败", e);
        }
    }

    /**
     * <desc>
     *  分页查询设备相关人员权限
     * <desc/>
     *
     * @param deviceUnique 设备唯一码
     * @param deviceType 1-电梯 2-门禁 3-云对讲
     * @param userType 1-业主 2-访客 3-临时
     * @return MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2020/06/02
     */
    @ResponseBody
    @PostMapping(path = "/getEquipUserInfo")
    public Object getEquipUserInfo(String deviceUnique, String deviceType, String userType, Integer currentPage, Integer pageSize) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            deviceUnique = request.getAttribute("deviceUnique") == null ? null : request.getAttribute("deviceUnique").toString();
            deviceType = request.getAttribute("deviceType") == null ? null : request.getAttribute("deviceType").toString();
            userType = request.getAttribute("userType") == null ? null : request.getAttribute("userType").toString();
            currentPage = request.getAttribute("currentPage") == null ? null : (Integer) request.getAttribute("currentPage");
            pageSize = request.getAttribute("pageSize") == null ? null : (Integer) request.getAttribute("pageSize");
            if(StringUtils.isEmpty(deviceUnique) || StringUtils.isEmpty(deviceType) || StringUtils.isEmpty(userType)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            currentPage = currentPage == null?1:currentPage;
            pageSize = pageSize == null?15:pageSize;
            Page<PropertyEquipUserInfoVO> equipUserInfo = iPropertyEquipServiceClient.getEquipUserInfo(deviceUnique,deviceType,userType,
                    currentPage,pageSize);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), equipUserInfo);
        } catch (Exception e) {
            throw new DataAccessException("【物业_系统_设备管理】根据设备查询相关人员权限失败", e);
        }
    }

    /**
     * <desc>
     *      Ftp上传文件，返回Url.
     * </desc>
     *
     * @param inputStream 文件流
     * @return 文件上传成功后会返回Url,否则返回空
     * @author wangzhi
     * @createDate 2018/11/06
     */
    private String uploadFile(InputStream inputStream) throws IOException {
        String fileUrl = "";
        UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                FILE_FTP_HOST,
                FILE_FTP_USERNAME,
                FILE_FTP_PASSWORD,
                FILE_FTP_PORT,
                inputStream,
                "jpg",
                FILE_ACCESS_URL,
                FileCatalogEnum.PARK_COUPON_QR_CODE_FILE.getType()
        );
        Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
        Boolean returnCode = (Boolean)resultMap.get("returnCode");
        if (!returnCode){
            return fileUrl;
        }
        fileUrl = resultMap.get("accessPath").toString();
        return fileUrl;
    }

    /**
     * <desc>
     *      测试用，用完删掉
     * </desc>
     *
     * @param
     * @return
     * @Author Zhu.yj
     * @createDate  2021/4/14
     */
    @PostMapping("testController")
    @UnParamEncrypt
    @UnAuthAccessRequired
    public Object testController(){
        try {
            PropertyEquipAuthGetDTO getDTO = new PropertyEquipAuthGetDTO();
            getDTO.setProjectId("00000144");
            getDTO.setDeviceType(2);
            getDTO.setPageSize("400");
            getDTO.setCurrentPage("1");
            return iPropertyEquipServiceClient.getUserEquipAuthByPage(getDTO);

        }catch (Exception e) {

        }
        return null;
    }

}
